package com.hyc.config;

import com.hyc.message.RpcResponse;
import io.github.resilience4j.circuitbreaker.CircuitBreaker;
import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig;
import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry;

import java.time.Duration;

/**
 * @author 冷环渊
 * rpc 接口可靠性保障之 熔断器
 * @date 2025/6/12 18:52
 * @description BreakerConfig
 */
public class BreakerConfig {
    public static CircuitBreaker getCircuitBreaker() {
        CircuitBreakerConfig config = CircuitBreakerConfig
                .custom()
                //当 RPC 响应的状态码为 500 时，记录为失败。
                .recordResult(response -> ((RpcResponse) response).getCode() == 500)
                //当失败率达到 50% 时，熔断器会打开。
                .failureRateThreshold(50)
                //当慢调用比例达到 50% 时，熔断器会打开。
                .slowCallRateThreshold(50)
                //调用耗时超过 2 秒视为慢调用。
                .slowCallDurationThreshold(Duration.ofSeconds(2))
                //熔断器打开后，10 秒后自动切换到半开状态。
                .waitDurationInOpenState(Duration.ofSeconds(10))
                .automaticTransitionFromOpenToHalfOpenEnabled(true)
                //在半开状态下允许 5 次调用，用于测试服务是否恢复。
                .permittedNumberOfCallsInHalfOpenState(5)
                .minimumNumberOfCalls(3)
                //使用基于计数的滑动窗口
                .slidingWindowType(CircuitBreakerConfig.SlidingWindowType.COUNT_BASED)
                .slidingWindowSize(15)
                .recordExceptions(Exception.class)
                .build();

        CircuitBreakerRegistry breakerRegistry = CircuitBreakerRegistry.of(config);
        return breakerRegistry.circuitBreaker("pinhaoRpcCircuitBreaker");
    }
}
